/*


 */

package jas.http.request;

import jas.http.server.HttpFormatException;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.regex.Pattern;

/**
 * Contains static methods for parsing and creating HTTP requests.
 */
public class HttpRequestFormatter {
    
	/**
	 * Creates a GET request for the specified URI.
	 * @param uri the URI to request.
	 * @return an HTTP request object
	 */
    public static HttpRequest createGETRequest(String uri) {
        HttpRequest request = new HttpRequest();
        request.setMethod("GET");
        request.setPath(uri);
        request.setVersion("HTTP/1.1");
        request.setBody("");
        return request;
    }
    
    /**
     * Parses an HTTP request from a buffered reader.
     * @param input a reader producing the textual representation of the request 
     * @return an HTTP request object
     * @throws IOException if the reader throws an IOException
     * @throws HttpFormatException if the message is not valid HTTP request syntax
     */
    public static HttpRequest parseRequest(BufferedReader input) throws IOException, HttpFormatException {
        StringBuffer buffer = new StringBuffer();
        String line;
        while ((line = input.readLine()) != null) {
            if (line.equals("")) {
                break;
            }
            buffer.append(line + "\r\n");
        }
        String request = buffer.toString();
        return parseRequest(request);
    }
    
    /**
     * Parses an HTTP request from a string.
     * @param request the textual representation of an HTTP request.
     * @return an HTTP request object
     * @throws HttpFormatException if the message is not valid HTTP request syntax
     */
    public static HttpRequest parseRequest(String request) throws HttpFormatException {
        HttpRequest req = new HttpRequest();
        
       // if (!isValidRequest(request)) 
        //    throw new HttpFormatException("Not valid: " + request);
        
        int headerIndex = request.indexOf("\r\n\r\n");
        String header = headerIndex == -1? request : request.substring(0, headerIndex);
        String body = headerIndex == -1? "" : request.substring(headerIndex + 4);
        
        String[] headerLines = header.split("\r\n");
        
        if (headerLines.length == 0)
            throw new HttpFormatException("Missing HTTP header");
        
        String[] tokens = headerLines[0].split(" ");
        
        if (tokens.length < 3)
            throw new HttpFormatException("Malformed request line: " + headerLines[0]);
        
        req.setMethod(tokens[0]);
        req.setPath(tokens[1]);
        req.setVersion(tokens[2]);
        
        int lineNumber = 1;
        while (lineNumber < headerLines.length && headerLines[lineNumber].length() > 0) {            
            tokens = headerLines[lineNumber].split(": ");
            
            if (tokens.length < 2)
                throw new HttpFormatException("Malformed header line: " + headerLines[lineNumber]);
            
            String headerName = tokens[0];
            String value = tokens[1].trim();
            req.setHeader(headerName, value);
            
            lineNumber++;
        }
        
        req.setBody(body);
        
        return req;
    }
    
    /**
     * Determines if an HTTP request is syntactically valid.
     * @param entireRequest the textual HTTP request
     * @return true if it is valid, false otherwise
     */
    public static boolean isValidRequest(String entireRequest) {
        String SP = " ";
        String method = "(GET)";
        
        String URI = "/([^\\n\\r]*)"; //beware of relative uri's
        
        String HTTPVersion = "HTTP/(1\\.1|1\\.0)";
        String key = "[^ :\\n\\r]+";
        String value = "[^\\n\\r]+";
        String CRLF = "\\r\\n";
        
        String requestLine = method+SP+URI+SP+HTTPVersion;
        String header = CRLF+key+":"+SP+value;
        String headers = "("+header+")*";
        //String maybeContent = "(\\r\\n.*)*"; 
        String maybeContent =  "(\\r\\n\\r\\n.*)?";
        
        /*
         * (GET) /([^\n\r]*) HTTP/(1\.1|1\.0)\r\n([^ :\n\r]+: [^\n\r]+\r\n)*(\r\n.*)*
         */
        String validHTTPRequestString = requestLine+headers+maybeContent;
        System.out.println(validHTTPRequestString);
        //System.out.println(httpRequest.entireRequest);
        return Pattern.compile(validHTTPRequestString).matcher(entireRequest).matches();
    }
    
}
